﻿// utilities.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "stdafx.h"
#include"FSMap.h"

DEF_string(type, "fs2_effect", "type");
DEF_string(input, "C:/迅雷下载/遗忘传说重置版客户端20240716/遗忘传说重置版20240705/FS2/reseffect", "input");
DEF_string(shadow_mask_file, "D:/resmap2/shadow_mask_file.txt", "shadow_mask_file");
DEF_string(output, "D:/res_effect", "output");

int main(int argc, char **argv)
{
    flag::init(argc, argv);

    fs::mkdir(FLG_output);
    if (FLG_type == "fs2_map")
    {
        fs::dir dir;
        dir.open(FLG_input);
        auto files = dir.all();

        //fs::file desc_file(path::join(FLG_input, "resmap.csv"), 'w');

		std::map<std::string, std::vector<cv::Vec3b>> map_shadow_color;
        fs::file shadow_mask;
        if (shadow_mask.open(FLG_shadow_mask_file.c_str(), 'r'))
        {
            auto file_content = shadow_mask.read(shadow_mask.size());
            auto vecLine = str::split(file_content, '\n');
            for (auto line : vecLine)
			{
				auto vec = str::split(line, ' ');
                if (vec.size() > 1)
				{
                    auto &colors = map_shadow_color[vec[0].c_str()];
					for (int i = 1; i < vec.size(); i++)
                    {
						auto color = str::split(vec[i], ',');
                        if (color.size() == 3)
                        {
                            colors.push_back(cv::Vec3b(std::stoi(color[2].c_str()), std::stoi(color[1].c_str()), std::stoi(color[0].c_str())));
                        }
                    }
				}
            }
        }


        for (auto& file : files)
        {
            //if (file.lower().ends_with("001.map"))
            {
                std::cout << file << std::endl;
                FSMap fs_map;
                fs_map.Load(path::join(FLG_input, file).c_str());
                auto masks = map_shadow_color[file.c_str()];
                if (masks.size() == 0)
                {
                    masks.push_back(cv::Vec3b(255, 0, 0));
                }
                fs_map.SaveMapPng(path::join(FLG_output, file + ".png").c_str(), masks);
                //break;
			}
		}
    }
    else if (FLG_type == "fs2_item")
    {
        fs::dir dir;
        dir.open(FLG_input);
        auto files = dir.all();

        //fs::file desc_file(path::join(FLG_input, "resmap.csv"), 'w');

        FSMap::Sprite sprite;
        sprite.widht = 32;
        sprite.height = 32;
        sprite.data_size = 1024;
		sprite.data = new uint8[1024];
		uint8 pal[0x300];
        for (auto& file : files)
        {
            if (file.lower().ends_with(".pal"))
            {
                auto name = file.substr(0, file.size() - 4);

				fs::file pal_file(path::join(FLG_input, file), 'r');
				pal_file.read(pal, 0x300);

                fs::file dat_file(path::join(FLG_input, name+"spr.dat"), 'r');

                int count = 0;
                dat_file.read(&count, 4);
				for (int i = 0; i < count; i++)
				{
					dat_file.read(sprite.data, 1024);
					FSMap::ConvertImage2(sprite, pal);
					cv::imwrite(path::join(FLG_output, fmt::format("{}_{:03d}.png", name.c_str(), i)).c_str(), sprite.image);
				}
            }
        }
        delete[] sprite.data;
    }
    else if (FLG_type == "fs2_effect")
    {
        fs::dir dir;
        dir.open(FLG_input);
        auto files = dir.all();
        std::vector<uint8_t> m_data;
        fs::file log_file(path::join(FLG_output, "sprite.log"), 'w');
        for (auto& file : files)
        {
            if (!file.ends_with("dragonstorm.fge") && !file.ends_with("lt-strike.fge"))
            {
                auto name = file.substr(0, file.size() - 4);
                log_file.write(name);
                log_file.write("\n");
				std::cout << name << std::endl;
                auto sprite_dir = path::join(FLG_output, name);
                fs::mkdir(sprite_dir, true);

                auto filePath = path::join(FLG_input, file);
                FILE* fp = NULL;
                fopen_s(&fp, filePath.c_str(), "rb");
                if (fp == 0)
                    continue;
                auto size = fs::fsize(filePath);
                m_data.resize(size);
                unsigned char* data = &m_data[0];
                fread(data, size, 1, fp);
                fclose(fp);

                uint32 len = *(uint32*)data; data += 4;
                uint32 type = *(uint32*)data; data += 4;
                uint32 count = *(uint32*)data; data += 4;

				log_file.write(fmt::format("len:{}, type:{}, count:{}\n", len, type, count));

                if (type > 0)
                {
                    log_file.write("\n\n");
                }
                else
                {
                    uint8_t* szPalete = &m_data[0] + size-0x300;
                    for (int i = 0; i < count; i++)
                    {
                        uint32 value[11];
                        FSMap::Sprite sprite;
                        for (int j = 0; j < 11; j++)
                        {
                            value[j] = *(uint32*)data; data += 4;
                            log_file.write(fmt::format("{} ", value[j]));
                        }
                        sprite.data = data;
						sprite.data_size = value[10];
                        log_file.write(fmt::format("\n"));
                        log_file.write(convertHex(sprite.data, sprite.data_size));
                        log_file.write(fmt::format("\n"));
						sprite.widht = value[8];
                        sprite.height = value[9];
                        FSMap::ConvertImage(sprite, szPalete);
                        cv::imwrite(path::join(sprite_dir, fmt::format("{}_{:03d}.png", name.c_str(), i)).c_str(), sprite.image);
                        data += value[10];
                    }
                }
                log_file.write("\n\n");
            }
        }
    }
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
